import React, { createContext, useContext, useEffect, useReducer, useCallback } from 'react';
import { Profiler, useId } from 'react';
import { withRouter, Prompt } from 'react-router-dom';

// // 创建 context 上下文
// export const ctx = createContext()

// 子组件中使用 context 上下文数据
function Test(props) {
  const { context } = props;
  // 获取 context 上下文对象
  const [contextVal, ctxDispatch] = useContext(context);
  // console.log('子组件中的 props 中的值', props, contextVal)

  useEffect(() => {
    /**
     * 惰性函数：只会在函数第一次调用的时候执行，在第一次调用的过程中，该函数会被覆盖为另一个按照书写好的函数
     * 之后再调用该函数时，就不再经过之前的分支了，执行的函数，也不是之前的函数了，而是经过修改后的函数；
     * 第一遍执行之后，第二遍就不会在执行。
     *
     */
    let inertFun = () => {
      inertFun = () => Date.now();
      return inertFun();
    };
    console.log(1, '惰性函数', inertFun());
    console.log(2, '惰性函数', inertFun());
    console.log(3, '惰性函数', inertFun());

    function Person(name) {
      this.name = name;
    }
    function sharedPerson(name) {
      console.log('name', name);
      let person = new Person(name);
      sharedPerson = () => {
        return person;
      };
      return sharedPerson();
    }
    const p1 = sharedPerson('ouda');
    const p2 = sharedPerson('oulanglang');
    console.log('惰性函数', p1);
    console.log('惰性函数', p2);
    console.log('惰性函数', p1 === p2);
  }, []);

  const add = () => {
    ctxDispatch({ type: 'add', val: 5.1 });
  };
  const minus = () => {
    ctxDispatch({ type: 'minus', val: 3 });
  };
  return (
    <React.Fragment>
      <h3>
        useContext 上下文的值：{contextVal.contextName}
        ---时间--- {contextVal.time}
        ---数值--- {contextVal.val}
      </h3>
      <div>
        <button onClick={add}>加+</button>
        <button onClick={minus}>减-</button>
      </div>
    </React.Fragment>
  );
}

/* context 全局上下文基本学习 */
function UseContextHook(props) {
  const react18Id = useId?.(); // React18 新API

  // 创建 context 上下文
  const ctx = createContext(null);
  // context上下文的值 --- 初始值
  const ctxInitVal = { contextName: 'tlx', time: 20230221, val: 555 };
  /**
   * useReducer 参数处理函数
   */
  const ctxReducerFun = useCallback((sate, action) => {
    // console.log('contextVal', sate, action)
    switch (action.type) {
      case 'add':
        return { ...sate, val: sate.val + action.val };
      case 'minus':
        return { ...sate, val: sate.val - action.val };
      default:
        return { ...sate };
    }
  }, []);
  /**
   * 全局上下文 context 中的值使用 useReducer 来包裹数据达到数据同步更新的效果
   * useReducer(() => {}, value)
   */
  const [ctxState, myCtxDispatch] = useReducer(ctxReducerFun, ctxInitVal);

  // const {history} = props
  // const pCtx = useContext(ctx)
  useEffect(() => {
    // 阻止跳转
    // history.block('阻塞跳转信息 禁止跳转！！')
    // const unBlock = history.block(() => {
    //   return '阻塞跳转信息 禁止跳转！！ '+props.location.pathname
    // })
    return () => {
      // unBlock()
    };
  }, []);

  // 性能测量树渲染开销回调
  const ctxCallback = () => {
    // console.log('时间调试组件回调！！！')
  };

  return (
    <Profiler id='useContextHookPage' onRender={ctxCallback}>
      <Prompt when={true} message={location => 'prompt 路由拦截！！！'} />
      {/* Provider 在指定的范围内，可以操作对象 */}
      <ctx.Provider value={[ctxState, myCtxDispatch]}>
        <h2>
          父级中context中的数据：{ctxState.contextName}---时间---{ctxState.time}---数值---{ctxState.val}
        </h2>
        <Test context={ctx} />
        <hr />
      </ctx.Provider>
    </Profiler>
  );
}

export default withRouter(UseContextHook);
